﻿namespace Cos.Admin
{
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;

    using Cos.Core;
    using Cos.Core.Attributes;
    using Cos.Core.Interception;
    using Cos.Core.Module;
    using Cos.Core.NHibernate;
    using Cos.Core.NHibernate.Mapping;
    using Cos.Core.Service;
    using Cos.Module.Security;
    using Cos.Module.Security.Admin;

    using FluentNHibernate;
    using FluentNHibernate.Cfg;
    using FluentNHibernate.Cfg.Db;

    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.Configuration;
    using Microsoft.Practices.Unity.InterceptionExtension;

    using NHibernate;
    using NHibernate.Context;

    using UserDataModel = Cos.Module.Security.NHibernate.UserDataModel;

    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        private const string SessionFactoryContextKey = "session_factory";

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Test", action = "Index", id = UrlParameter.Optional }); // Parameter defaults
        }

        protected void Application_Start()
        {
            // create dependency container
            var container = new UnityContainer();
            container.AddNewExtension<InterceptOnRegisterContainerExtension>();

            // configure container
            var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            section.Configure(container);

            ///// TEST
            var test = new NHibernate.Cfg.Configuration();
            test.Configure();

            Fluently.Configure(test)
                           .Mappings(m => m.FluentMappings.AddFromAssembly(typeof(PageDataModel).Assembly))
                           .BuildSessionFactory(); 
            /////

            // configure session manager
            container.RegisterType<ISessionManager, NHibernateSessionManager>(new PerRequestLifetimeManager("session_manager"));

            // configure session factory
            container.RegisterType<ISessionFactory>(
                new PerRequestLifetimeManager(SessionFactoryContextKey),
                new InjectionFactory(
                    c =>
                        {
                            return NHibernateHelper.SessionFactory;

                            //var ncfg = new NHibernate.Cfg.Configuration();
                            //ncfg.Configure();

                            //return Fluently.Configure(ncfg)
                            //               .Mappings(m => m.FluentMappings.AddFromAssembly(typeof(PageDataModel).Assembly))
                            //               .BuildSessionFactory();
                            /*
                        var cfg = Fluently.Configure()
                       .Database(MsSqlConfiguration.MsSql2008
                           .ConnectionString(@"Data Source=.\Dev2008;Initial Catalog=CameleonCMS;Integrated Security=SSPI;").ShowSql().CurrentSessionContext<ThreadLocalSessionContext>());

                        var model = new PersistenceModel();
                        model.AddMappingsFromAssembly(typeof(PageDataModel).Assembly);
                        
                        var sessionSource = new SessionSource(cfg.BuildConfiguration().Properties, model);

                        return sessionSource.Configuration.BuildSessionFactory();*/
                        }));

            // create unity dependency resolver
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));

            // TODO Set the service locator
            ServiceLocator.Container = container;

            log4net.Config.XmlConfigurator.Configure();

            // register areas
            AreaRegistration.RegisterAllAreas();

            // register basic mvc settings
            RegisterGlobalFilters(GlobalFilters.Filters);

            // register routes
            RegisterRoutes(RouteTable.Routes);

        }

        protected void Application_EndRequest(object sender, EventArgs e)
        {
            var currentSession = HttpContext.Current.Items[SessionFactoryContextKey] as ISession;
            if (currentSession != null)
            {
                currentSession.Close();
            }
        }
    }
}